<?php
/*
 * This library is free software; you can redistribute it and/or modify it 
 * under the terms of the BSD License.
 *
 * This library is distributed in the hope that it will be useful, but 
 * WITHOUT ANY WARRANTY; without even the implied warranty of 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
 */

/**
 * An implementation of the GoogleCheckoutServer that records all incoming
 * and outgoing messages to a database and keeps proper state.
 *
 * @author Byrne Reese <byrne@majordojo.com>
 * @copyright 2006-2008, Byrne Reese.
 * @package GoogleCheckout
 */

/**
 * @ignore
 */
require_once("GoogleCheckoutServer.php");

/**
 * @todo Move to another file
 * @todo Get rid of Test Run stuff
 */
function connect_to_db() {
  global $TESTRUN_IS_CONNECTED;
  if (isset($TESTRUN_IS_CONNECTED)) { return; }
  if (!mysql_connect(MYSQL_HOST, MYSQL_USER, MYSQL_PASS)) {
    // couldn't connect
    echo "could not connect (".MYSQL_HOST.", ".
      MYSQL_USER.", ".MYSQL_PASS.")"; 	
  }
  if (!mysql_select_db(MYSQL_DB)) {
    // couldn't connect
    echo "could not select (".MYSQL_DB.")"; 	
  }
  $TESTRUN_IS_CONNECTED = 1; 
}

/**
 * @package GoogleCheckout
 * @example ExampleGoogleCheckoutServer.php
 */
class MySQLGoogleCheckoutServer extends GoogleCheckoutServer {

  function doChargeAmountNotification($request,$response) {
    $this->log($request->serialNumber(),$request->orderNumber(),
	       "Charged order: " . 
	       $request->totalChargeAmount());
  }
  function doMerchantCalculationCallback($request,$response) {
    $this->log($request->serialNumber(),$request->orderNumber(),
	       "Received callback - $request");
    
  }
  function doNewOrderNotification($request,$response) {
    $this->log($request->serialNumber(),$request->orderNumber(),
	       "New order notification received - amount: " . 
	       $request->orderTotal());
    $request->order->insert();
  }

  function doOrderStateChangeNotification($request,$response) {
    if ($request->previousFulfillmentState() != $request->fulfillmentState()) {
      $this->log($request->serialNumber(),$request->orderNumber(),
		 "Changing fulfillment state from " .
		 $request->previousFulfillmentState() . " to " . 
		 $request->fulfillmentState().".");
    }
    if ($request->previousFinancialState() != $request->financialState()) {
      $this->log($request->serialNumber(),$request->orderNumber(),
		 "Changing financial state from " .
		 $request->previousFinancialState() . " to " . 
		 $request->financialState().".");
    }
    $sql = sprintf("
          UPDATE ".MYSQL_DB.".orders SET
              fulfillment_state = '%s',
              financial_state = '%s'
            WHERE order_number = '%s'",
		   mysql_escape_string($request->fulfillmentState()),
		   mysql_escape_string($request->financialState()),
		   mysql_escape_string($request->orderNumber())
		   );
    $this->log($request->serialNumber(),$request->orderNumber(),$sql);
    $query = mysql_query($sql) or die("Error: $sql -- " . mysql_error());
  }

  function doRiskInformationNotification($request,$response) {
    $this->log($request->serialNumber(),$request->orderNumber(),
	       "Received risk information.");
    $sql = sprintf("
          UPDATE ".MYSQL_DB.".orders SET
                eligible_for_protection = %d,
                avs_response = '%s',
                cvn_response = '%s',
                partial_cc_number = '%s',
                buyer_account_age = %d,
                ip_address = '%s'
            WHERE order_number = '%s'",
		   $request->eligibleForProtection(),
		   mysql_escape_string($request->avsResponse()),
		   mysql_escape_string($request->cvnResponse()),
		   mysql_escape_string($request->partialCCNumber()),
		   $request->buyerAccountAge(),
		   mysql_escape_string($request->ipAddress()),
		   mysql_escape_string($request->orderNumber())
		   );
    $query = mysql_query($sql) or die("Error: $sql -- " . mysql_error());
  }

  function readyToChargeOrder($order) {
    $sql = sprintf("
          SELECT fulfillment_state,financial_state,avs_response
            FROM ".MYSQL_DB.".orders
           WHERE order_number = '%s'",
		   mysql_escape_string($order)
		   );
    $query = mysql_query($sql) or die("Error: $sql -- " . mysql_error());
    if ($query && (mysql_num_rows($query) > 0)) {
      list($fulfillmentState,$financialState,$avsResponse) 
	= mysql_fetch_row($query);
      if (isset($avsResponse) && $financialState == "CHARGEABLE") {
	$this->log("",$order,"Sendinging Charge Order Command.");
	return CHARGE;
      } else {
	// return DONTCHARGE;
      }
    }
    return WAIT;
  }

  function getOrderAmount($order) {
    $sql = sprintf("
          SELECT order_total,tax_total,adjustment_total
            FROM ".MYSQL_DB.".orders
           WHERE order_number = '%s'",
		   mysql_escape_string($order)
		   );
    $query = mysql_query($sql) or die("Error: $sql -- " . mysql_error());
    if ($query && (mysql_num_rows($query) > 0)) {
      list($total,$tax,$adjustment) = mysql_fetch_row($query);
      return $total;
    }
    return 0;
  }

  protected function log($sn,$on,$msg) {
    $sql = sprintf("
          INSERT INTO ".MYSQL_DB.".transaction_log
                      (serial_number,order_number,message,created_date)
               VALUES ('%s','%s','%s',NOW())",
		  mysql_escape_string($sn),
		  mysql_escape_string($on),
		  mysql_escape_string($msg));
    $query = mysql_query($sql) or die("Error: $sql -- " . mysql_error());
  }

}
?>